# file cache. both mcache and dcache implement this.
# used by ofs. 

# Nowhere near were it should be. Clumsy interface.
# The moment we decide to write dchache.b both caches
# should be rewritten and this interface cleaned up.

Cache: module {
	PATH: con "/dis/o/mcache.dis";

	MAXNMSGS:	con 4;
	MAXCACHED:	con MAXNMSGS * Op->MAXDATA;

	Cfile: adt {
		opfd:	int;					# fd in Tputs. Used by stop.b
		d:		ref Sys->Dir;
		data:	array of byte;
		dirread: int;					# directory data has been read
		dirtyd:	int;
		created:	int;
		oldname:	string;				# for renames
		parentqid:	big;
		serverqid:	Sys->Qid;			# coherency
		child:	cyclic ref Cfile;
		sibling:	cyclic ref Cfile;
		hash:	cyclic ref Cfile;
		time: int;						# when last known to be coherent
	
	};

	Creq: adt {
		qid: big;				# qid for file we are asking about
		f: ref Cfile;			# quick ref for file (qid unused if not null)
		pick {
		Dump or Stat or Info or Flush or Remove=>
		Readdir =>
			off: int;
			cnt: int;
		Validate or Create=>
			name: string;			# name relative to f
			d:	ref Sys->Dir;		# for named file
			data: array of byte;		# for named file
		Invalidate or Walk1 or Valid =>
			name: string;			# name relative to f
		Wstat =>
			d: ref Sys->Dir;
			dirties: int;
		Pread =>
			cnt: int;
			off: big;
		Pwrite =>
			data: array of byte;
			off : big;
			dirties: int;
		}
		text:	fn(fh: self ref Creq): string;
	};
	
	Crep: adt {
		err : string;			# for failing requests
		f: ref Cfile;			# direct ref for file. (a Creq.f the next time)
		pick {
		Stat or Validate or Walk1 or Wstat or Create =>
			d: ref Sys->Dir;	# copy. no races.
		Info =>
			path: string;		# for file in server
			d: ref Sys->Dir;
			dirty: int;
		Remove or Pwrite =>
			path: string;		# for file in server
		Invalidate or Dump=>
		Valid =>
			d: ref Sys->Dir;
			uerr : string;
		Readdir =>
			sons: list of Sys->Dir;
		Pread =>
			path: string;
			data: array of byte;
		Flush =>
			path: string;		# for file in server
			d: ref Sys->Dir;
			created: int;
		}
	};

	# styx for unpackdir
	init:		fn(s: Styx, cdir: string, lag: int) : string;
	term:		fn();
	cacherpc:	fn(r: ref Creq) : ref Crep;
	debug:	int;
};
